<!DOCTYPE html>
<html><head>
<style type="text/css">
	td {
		background: lightblue;
		padding: 0.5em;
	}
</style>
</head><body onload="makeImages()">

<img id="reference" src="barretr_Earth.png" width="100" height="100" />

<script type="text/javascript">

function blurredPoint(kernel, points) {
	var rgb = [0, 0, 0, 0];
	var totalWeight = 0;
	for (var i = 0; i < kernel.length; i++)
		if (points[i]) {
			totalWeight += kernel[i];
			var alpha = points[i][3] / 255;
			rgb[0] += points[i][0] * kernel[i] * alpha;
			rgb[1] += points[i][1] * kernel[i] * alpha;
			rgb[2] += points[i][2] * kernel[i] * alpha;
			rgb[3] += points[i][3] * kernel[i] * alpha;
		}
	rgb[0] = Math.round(rgb[0]/totalWeight);
	rgb[1] = Math.round(rgb[1]/totalWeight);
	rgb[2] = Math.round(rgb[2]/totalWeight);
	rgb[3] = Math.round(rgb[3]/totalWeight);
	return rgb;
}

function getPointRGBA(imageData, x, y, w, h) {
	if (x < 0 || x >= w || y < 0 || y >= h)
		return null;
	var offset = (y * w + x) * 4;
	return [
		imageData.data[offset],
		imageData.data[offset+1],
		imageData.data[offset+2],
		imageData.data[offset+3]
	];
}

function createImageWithFilter(reference, filters) {
	filters = filters.split(',');
	var canvas = document.createElement('canvas');
	var w = canvas.width = reference.width;
	var h = canvas.height = reference.height;
	
	var context = canvas.getContext('2d');
	context.drawImage(reference, 0, 0, w, h);
	var dataIn = context.getImageData(0, 0, w, h);
	var dataOut = context.getImageData(0, 0, w, h);
	for (var fi = 0; fi < filters.length; fi++) {
		var t = dataIn;
		dataIn = dataOut;
		dataOut = t;
		switch (filters[fi]) {
			case "grayscale":
				for (var x = 0; x < w; x++)
					for (var y = 0; y < h; y++) {
						var offset = (y * w + x) * 4;
						var r = dataIn.data[offset];
						var g = dataIn.data[offset+1];
						var b = dataIn.data[offset+2];
						var luma = Math.round((30 * r + 59 * g + 11 * b ) / 100);
						r = g = b = luma;
						dataOut.data[offset] = r;
						dataOut.data[offset+1] = g;
						dataOut.data[offset+2] = b;
					}
				break;
			case "blur":
				var kernel = [7, 26, 41, 26, 7];
				// horizontal
				for (var x = 0; x < w; x++)
					for (var y = 0; y < h; y++) {
						var rgba = blurredPoint(kernel, [
							getPointRGBA(dataIn, x-1, y, w, h),
							getPointRGBA(dataIn, x, y, w, h),
							getPointRGBA(dataIn, x+1, y, w, h)
						]);
						var offset = (y * w + x) * 4;
						dataOut.data[offset] = rgba[0];
						dataOut.data[offset+1] = rgba[1];
						dataOut.data[offset+2] = rgba[2];
						dataOut.data[offset+3] = rgba[3];
					}
				var t = dataIn;
				dataIn = dataOut;
				dataOut = t;
				// vertical
				for (var x = 0; x < w; x++)
					for (var y = 0; y < h; y++) {
						var rgba = blurredPoint(kernel, [
							getPointRGBA(dataIn, x, y-1, w, h),
							getPointRGBA(dataIn, x, y, w, h),
							getPointRGBA(dataIn, x, y+1, w, h)
						]);
						var offset = (y * w + x) * 4;
						dataOut.data[offset] = rgba[0];
						dataOut.data[offset+1] = rgba[1];
						dataOut.data[offset+2] = rgba[2];
						dataOut.data[offset+3] = rgba[3];
					}
				break;
		}
	}
	context.putImageData(dataOut, 0, 0);
	
	document.body.appendChild(canvas);
}

function makeImages() {
	var reference = document.getElementById('reference');
	createImageWithFilter(reference, 'grayscale');
	document.body.appendChild(document.createElement('br'));
	createImageWithFilter(reference, 'blur');
	createImageWithFilter(reference, 'grayscale,blur');
}

</script>

</body></html>
